package com.terry.trace.plugin;

import com.terry.trace.core.LogTagTool;
import com.terry.trace.core.util.IdGenerator;
import com.terry.trace.core.util.StringUtil;
import com.terry.trace.core.TraceLogger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * trace servlet 过滤器
 * 参考 https://www.cnblogs.com/wpcnblog/p/12358112.html
 * @author TerryJiang
 */
public class TraceServletFilter implements Filter {

    private static final TraceLogger logger = TraceLogger.getLogger(TraceServletFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String flowNo = httpServletRequest.getHeader(LogTagTool.LOG_TAG_FLOW_NO);
        flowNo = StringUtil.isNoTrimEmpty(flowNo) ? flowNo : IdGenerator.generateFlowNo();
        try {
            LogTagTool.putFlowNo(flowNo);
        } catch (Exception exception) {
            LogTagTool.removeContextLogTag();
            logger.warn("TraceServletFilter.doFilter 设置flowNo失败.", exception);
        }
        try {
            chain.doFilter(request, response);
        } catch (Exception exception) {
            logger.warn("TraceServletFilter.doFilter chain.doFilter() 异常.", exception);
        } finally {
            // 要放在最后一步执行，关键步骤，清空上下文中的log tag, 用来防止内存泄露，或者产生脏数据
            LogTagTool.removeContextLogTag();
        }
    }
}
